﻿// Copyright (c) JosephZheng. All rights reserved. See License.txt in the project root for license

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;

namespace Lyra.Cache.Client
{
    internal class WcfHelper<T>
    {
        public static object ExecuteMethod(string url, string methodName, params object[] args)
        {
            EndpointAddress address = new EndpointAddress(url);
            Binding bindinginstance = null;
            NetTcpBinding ws = new NetTcpBinding();
            ws.CloseTimeout = TimeSpan.FromSeconds(30);
            ws.ReceiveTimeout = TimeSpan.FromMinutes(10);
            ws.SendTimeout = TimeSpan.FromMinutes(10);
            ws.MaxBufferPoolSize = 524288;
            ws.MaxBufferSize = 2147483647;
            ws.MaxConnections = 32768;
            ws.MaxReceivedMessageSize = 2147483647;
            ws.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas() { MaxDepth = 256, MaxArrayLength = 4194304, MaxBytesPerRead = 1048576, MaxNameTableCharCount = 1048576, MaxStringContentLength = 4194304 };
            ws.Security.Mode = SecurityMode.None;
            ws.TransferMode = TransferMode.Streamed;
            bindinginstance = ws;
            using (ChannelFactory<T> channel = new ChannelFactory<T>(bindinginstance, address))
            {
                T instance = channel.CreateChannel();
                using (instance as IDisposable)
                {
                    try
                    {
                        Type type = typeof(T);
                        MethodInfo mi = type.GetMethod(methodName);
                        return mi.Invoke(instance, args);
                    }
                    catch (System.Exception ex)
                    {
                        try
                        {
                            (instance as ICommunicationObject).Close();
                        }
                        catch
                        {
                            (instance as ICommunicationObject).Abort();
                        }
                        throw ex;
                    }
                }
            }
        }  
    }
}
